using Circus.CodeEditor;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
namespace Circus.CodeEditor.TextSource
{
	public class Braces {
		internal class BraceItem
		{
			public int X;
			public bool Open;
			public int BraceIndex;
			public BraceItem(int x)
			{
				this.X = x;
			}
			public BraceItem(int x, int braceIndex, bool open)
			{
				this.X = x;
				this.BraceIndex = braceIndex;
				this.Open = open;
			}
		}
		internal class BraceLine
		{
			private Braces.BraceItemList braces;
			private int line;
			public int Line
			{
				get
				{
					return this.line;
				}
				set
				{
					this.line = value;
				}
			}
			public Braces.BraceItemList Braces
			{
				get
				{
					return this.braces;
				}
			}
			public BraceLine(int line)
			{
				this.braces = new Braces.BraceItemList();
				this.line = line;
			}
			~BraceLine()
			{
				this.braces.Clear();
			}
			public bool FindBrace(int x, out int index)
			{
				return this.braces.FindBrace(x, out index);
			}
			public bool FindLast(int x, out int index)
			{
				return this.braces.FindLast(x, out index);
			}
			public void AddBrace(Braces.BraceItem brace)
			{
				this.braces.AddBrace(brace);
			}
		}
		private class ExactBraceComparer : IComparer<Braces.BraceItem>
		{
			public int Compare(Braces.BraceItem x, Braces.BraceItem y)
			{
				return x.X - y.X;
			}
		}
		private class BraceComparer : IComparer<Braces.BraceItem>
		{
			public int Compare(Braces.BraceItem x, Braces.BraceItem y)
			{
				return (y.X > x.X) ? 0 : 1;
			}
		}
		private class ExactComparer : IComparer<Braces.BraceLine>
		{
			public int Compare(Braces.BraceLine x, Braces.BraceLine y)
			{
				return x.Line - y.Line;
			}
		}
		private class LineComparer : IComparer<Braces.BraceLine>
		{
			public int Compare(Braces.BraceLine x, Braces.BraceLine y)
			{
				return (y.Line >= x.Line) ? 0 : 1;
			}
		}
		internal class BraceItemList : SortList<Braces.BraceItem>
		{
			private IComparer<Braces.BraceItem> braceComparer;
			private IComparer<Braces.BraceItem> exactBraceComparer;
			public BraceItemList()
			{
				this.braceComparer = new Braces.BraceComparer();
				this.exactBraceComparer = new Braces.ExactBraceComparer();
			}
			public void AddBrace(Braces.BraceItem brace)
			{
				int index;
				base.FindLast(brace, out index, this.exactBraceComparer);
				base.Insert(index, brace);
			}
			public bool FindBrace(int x, out int index)
			{
				return base.FindExact(new Braces.BraceItem(x), out index, this.exactBraceComparer);
			}
			public bool FindLast(int x, out int index)
			{
				return base.FindLast(new Braces.BraceItem(x), out index, this.braceComparer);
			}
		}
		internal class BracesList : SortList<Braces.BraceLine>
		{
			private IComparer<Braces.BraceLine> exactComparer;
			private IComparer<Braces.BraceLine> lineComparer;
			public new Braces.BraceLine this[int index]
			{
				get
				{
					return base[index];
				}
			}
			public BracesList()
			{
				this.exactComparer = new Braces.ExactComparer();
				this.lineComparer = new Braces.LineComparer();
			}
			public bool BlockDeleting(Rectangle rect)
			{
				bool result = false;
				int num;
				base.FindFirst(new Braces.BraceLine(rect.Bottom), out num, this.exactComparer);
				if (num >= 0)
				{
					for (int i = Math.Min(num, base.Count - 1); i >= 0; i--)
					{
						Braces.BraceLine braceLine = this[i];
						if (braceLine.Line >= rect.Top && braceLine.Line <= rect.Bottom)
						{
							result = true;
							base.RemoveAt(i);
						}
						else
						{
							if (braceLine.Line < rect.Top)
							{
								break;
							}
						}
					}
				}
				return result;
			}
			public bool PositionChanged(int x, int y, int deltaX, int deltaY)
			{
				bool result;
				if (deltaY == 0)
				{
					result = false;
				}
				else
				{
					int num;
					base.FindFirst(new Braces.BraceLine(y), out num, this.exactComparer);
					if (num >= 0)
					{
						bool flag = false;
						for (int i = num; i < base.Count; i++)
						{
							Braces.BraceLine braceLine = this[i];
							Point point = new Point(0, braceLine.Line);
							if (SortList<Braces.BraceLine>.UpdatePos(x, y, deltaX, deltaY, ref point, true))
							{
								if (deltaX != 0 && deltaY != 0)
								{
									foreach (Braces.BraceItem current in braceLine.Braces)
									{
										Point point2 = new Point(current.X, braceLine.Line);
										if (SortList<Braces.BraceLine>.UpdatePos(x, y, deltaX, deltaY, ref point2, true))
										{
											current.X = point2.X;
										}
									}
								}
								braceLine.Line = point.Y;
								flag = true;
							}
						}
						if (flag)
						{
							if (base.NeedSort(this.exactComparer))
							{
								base.Sort(this.exactComparer);
							}
							result = true;
							return result;
						}
					}
					result = false;
				}
				return result;
			}
			public void AddBrace(int y, int x, int braceIndex, bool open)
			{
				Braces.BraceLine braceLine = new Braces.BraceLine(y);
				int index;
				if (base.FindLast(braceLine, out index, this.exactComparer))
				{
					braceLine = this[index];
				}
				else
				{
					braceLine = new Braces.BraceLine(y);
					base.Insert(index, braceLine);
				}
				braceLine.AddBrace(new Braces.BraceItem(x, braceIndex, open));
			}
			public void RemoveBraces(int line)
			{
				int index;
				if (base.FindLast(new Braces.BraceLine(line), out index, this.exactComparer))
				{
					base.RemoveAt(index);
				}
			}
			public bool FindBrace(Point position, out bool open)
			{
				open = false;
				int index;
				bool result;
				if (base.FindLast(new Braces.BraceLine(position.Y), out index, this.exactComparer))
				{
					Braces.BraceLine braceLine = this[index];
					if (braceLine.FindBrace(position.X, out index))
					{
						open = braceLine.Braces[index].Open;
						result = true;
						return result;
					}
				}
				result = false;
				return result;
			}
			public bool FindClosingBrace(ref Point position, ref int braceIndex, int bracesLen)
			{
				int num;
				bool result;
				if (base.FindLast(new Braces.BraceLine(position.Y), out num, this.lineComparer))
				{
					int[] array = new int[bracesLen];
					for (int i = 0; i < array.Length; i++)
					{
						array[i] = 1;
					}
					for (int i = num; i < base.Count; i++)
					{
						Braces.BraceLine braceLine = this[i];
						int num2 = 0;
						if (braceLine.Line == position.Y)
						{
							num2 = (braceLine.FindLast(position.X, out num) ? (num + 1) : braceLine.Braces.Count);
						}
						for (int j = num2; j < braceLine.Braces.Count; j++)
						{
							Braces.BraceItem braceItem = braceLine.Braces[j];
							if (braceItem.BraceIndex < bracesLen)
							{
								if (braceItem.Open)
								{
									array[braceItem.BraceIndex]++;
								}
								else
								{
									array[braceItem.BraceIndex]--;
									if (array[braceItem.BraceIndex] == 0 && (braceIndex < 0 || braceIndex == braceItem.BraceIndex))
									{
										position = new Point(braceItem.X, braceLine.Line);
										braceIndex = braceItem.BraceIndex;
										result = true;
										return result;
									}
								}
							}
						}
					}
				}
				result = false;
				return result;
			}
			public bool FindOpenBrace(ref Point position, ref int braceIndex, int bracesLen)
			{
				int num;
				bool result;
				if (base.FindLast(new Braces.BraceLine(position.Y), out num, this.lineComparer))
				{
					int[] array = new int[bracesLen];
					for (int i = 0; i < array.Length; i++)
					{
						array[i] = 1;
					}
					for (int i = num; i >= 0; i--)
					{
						Braces.BraceLine braceLine = this[i];
						int num2 = braceLine.Braces.Count - 1;
						if (braceLine.Line == position.Y)
						{
							num2 = (braceLine.FindLast(position.X, out num) ? num : -1);
						}
						for (int j = num2; j >= 0; j--)
						{
							Braces.BraceItem braceItem = braceLine.Braces[j];
							if (braceItem.BraceIndex < bracesLen)
							{
								if (!braceItem.Open)
								{
									array[braceItem.BraceIndex]++;
								}
								else
								{
									array[braceItem.BraceIndex]--;
									if (array[braceItem.BraceIndex] == 0 && (braceIndex < 0 || braceIndex == braceItem.BraceIndex))
									{
										position = new Point(braceItem.X, braceLine.Line);
										braceIndex = braceItem.BraceIndex;
										result = true;
										return result;
									}
								}
							}
						}
					}
				}
				result = false;
				return result;
			}
		}
		private Color foreColor = EditConsts.DefaultBracesForeColor;
		private Color backColor = EditConsts.DefaultBracesBackColor;
		private bool useRoundRect = false;
		private FontStyle fontStyle = EditConsts.DefaultBracesFontStyle;
		private CodeEditor owner;
		[Description("Gets or sets a value that represents foreground color to draw matching braces.")]
		public virtual Color ForeColor
		{
			get
			{
				return this.foreColor;
			}
			set
			{
				if (this.foreColor != value)
				{
					this.foreColor = value;
					this.OnForeColorChagned();
				}
			}
		}
		[Description("Gets or sets a value that represents background color to draw matching braces.")]
		public virtual Color BackColor
		{
			get
			{
				return this.backColor;
			}
			set
			{
				if (this.backColor != value)
				{
					this.backColor = value;
					this.OnBackColorChagned();
				}
			}
		}
		[Description("Gets or sets a FontStyle value that is used to draw matching braces.")]
		public virtual FontStyle FontStyle
		{
			get
			{
				return this.fontStyle;
			}
			set
			{
				if (this.fontStyle != value)
				{
					this.fontStyle = value;
					this.OnFontStyleChagned();
				}
			}
		}
		[DefaultValue(false), Description("ets or sets a boolean value that indicates whether Edit control should draw rectangle around matching braces.")]
		public virtual bool UseRoundRect
		{
			get
			{
				return this.useRoundRect;
			}
			set
			{
				if (this.useRoundRect != value)
				{
					this.useRoundRect = value;
					this.OnUseRoundRectChanged();
				}
			}
		}
		[DefaultValue(BracesOptions.None), Description("Gets or sets options specifying appearance and behaviour of matching braces within Edit control."), Editor("QWhale.Design.FlagEnumerationEditor, QWhale.Design", typeof(UITypeEditor))]
		public virtual BracesOptions BracesOptions
		{
			get
			{
				return (this.owner != null) ? this.owner.Source.BracesOptions : BracesOptions.None;
			}
			set
			{
				if (this.owner != null)
				{
					this.owner.Source.BracesOptions = value;
				}
			}
		}
		[Description("Gets or sets an array of characters each one representing an open brace.")]
		public virtual char[] OpenBraces
		{
			get
			{
				return (this.owner != null) ? this.owner.Source.OpenBraces : null;
			}
			set
			{
				if (this.owner != null)
				{
					this.owner.Source.OpenBraces = value;
				}
			}
		}
		[Description("Gets or sets an array of characters each one representing a closing brace.")]
		public virtual char[] ClosingBraces
		{
			get
			{
				return (this.owner != null) ? this.owner.Source.ClosingBraces : null;
			}
			set
			{
				if (this.owner != null)
				{
					this.owner.Source.ClosingBraces = value;
				}
			}
		}
	
		protected void Update()
		{
			if (this.BracesOptions != BracesOptions.None && this.owner != null)
			{
				this.owner.Invalidate();
			}
		}
		protected virtual void OnForeColorChagned()
		{
			this.Update();
		}
		protected virtual void OnBackColorChagned()
		{
			this.Update();
		}
		protected virtual void OnFontStyleChagned()
		{
			this.Update();
		}
		protected virtual void OnUseRoundRectChanged()
		{
			this.Update();
		}
		public Braces(CodeEditor owner)
		{
			this.owner = owner;
		}
		
		public virtual bool FindClosingBrace(ref int x, ref int y)
		{
			return this.owner != null && this.owner.Source.FindClosingBrace(ref x, ref y);
		}
		public virtual bool FindClosingBrace(ref Point position)
		{
			return this.owner != null && this.owner.Source.FindClosingBrace(ref position);
		}
		public virtual bool FindOpenBrace(ref int x, ref int y)
		{
			return this.owner != null && this.owner.Source.FindOpenBrace(ref x, ref y);
		}
		public virtual bool FindOpenBrace(ref Point position)
		{
			return this.owner != null && this.owner.Source.FindOpenBrace(ref position);
		}
		public virtual void TempHighlightBraces(Rectangle[] rects)
		{
			if (this.owner != null)
			{
				this.owner.Source.TempHighlightBraces(rects);
			}
		}
		public virtual void TempUnhighlightBraces()
		{
			if (this.owner != null)
			{
				this.owner.Source.TempUnhighlightBraces();
			}
		}
		public virtual void HighlightBraces()
		{
			if (this.owner != null)
			{
				this.owner.Source.HighlightBraces();
			}
		}
		public virtual void UnhighlightBraces()
		{
			if (this.owner != null)
			{
				this.owner.Source.UnhighlightBraces();
			}
		}
		public virtual void ResetBracesOptions()
		{
			this.BracesOptions = BracesOptions.None;
		}
		public virtual void ResetOpenBraces()
		{
			this.OpenBraces = EditConsts.DefaultOpenBraces;
		}
		public virtual void ResetClosingBraces()
		{
			this.ClosingBraces = EditConsts.DefaultClosingBraces;
		}
	}
}
